<template>
  <div v-loading="state.loading" class="bg-gray pd0 gap16 flex-column height-all">
    <div class="top bg-white pd10">
      <div class="bold mgb10">代理概览</div>
      <div class="gap20 flex-row-center-between">
        <TopOverviewItem title="代理总数" :count="state.data.agentOverview.sumCount" icon-name="multi-user" />
        <TopOverviewItem title="在线代理" :count="state.data.agentOverview.onlineCount" icon-name="computer" />
        <TopOverviewItem title="本月新增" :count="state.data.agentOverview.currentMonthCount" icon-name="book" />
        <TopOverviewItem title="总在线率" :count="state.data.agentOverview.onlineRate" icon-name="rate-online" />
        <TopOverviewItem :title="yoyTopObj.text" :count="yoyTopObj.value" icon-name="rate-yoy" />
      </div>
    </div>

    <div class="flex flex1 gap16" style="height: calc(100% - 300px)">
      <div class="flex-column flex1 height-all gap16">
        <!------------------------------------------ 月度 ------------------------------------------------------->

        <div class="flex1 bg-white flex-column-left-center height-all pd16">
          <div v-show="state.data.agentTrend?.agentCountByMonthList?.length" class="flex1 flex-column height-all">
            <div class="flex-row-center-left">
              <div class="bold">代理增长趋势 月度</div>
              <div class="mgl30 flex-row-center-left">
                <SelectVue style="width: 150px" v-model="state.monthQuery.startTime" :option-list="monthRange" @change="onMonthChange" :clearable="false" />
                <span class="grey-text mgl5 mgr5">至</span>
                <SelectVue style="width: 150px" v-model="state.monthQuery.endTime" :option-list="monthRange" @change="onMonthChange" :clearable="false" />
              </div>
            </div>
            <div class="flex-row-center-between height-all">
              <div id="graph-month" class="graph flex1 width-all height-all"></div>
              <GraphDesc
                style="width: 240px"
                :max-count="state.monthGraphData.maxFaultCountItem"
                :min-count="state.monthGraphData.minFaultCountItem"
                :max-mom="state.monthGraphData.maxMomRatioItem"
                :min-mom="state.monthGraphData.minMomRatioItem"
                :max-yoy="state.monthGraphData.maxYoyBasisItem"
                :min-yoy="state.monthGraphData.minYoyBasisItem"
              />
            </div>
          </div>
          <empty v-if="!state.data.agentTrend?.agentCountByMonthList?.length" />
        </div>

        <!------------------------------------------ 季度 ------------------------------------------------------->

        <div class="flex1 bg-white flex-column-left-center height-all pd16">
          <div v-show="state.data.agentTrend?.agentCountByQuarterList?.length" class="flex1 flex-column height-all">
            <div class="flex-row-center-left">
              <div class="bold">代理增长趋势 季度</div>
              <div class="mgl30 flex-row-center-left">
                <SelectVue style="width: 150px" v-model="state.quarterQuery.startTime" :option-list="quarterRange" @change="onQuarterChange" :clearable="false" />
                <span class="grey-text mgl5 mgr5">至</span>
                <SelectVue style="width: 150px" v-model="state.quarterQuery.endTime" :option-list="quarterRange" @change="onQuarterChange" :clearable="false" />
              </div>
            </div>
            <div class="flex-row-center-between height-all">
              <div id="graph-quarter" class="graph flex1 width-all height-all"></div>
              <GraphDesc
                style="width: 240px"
                :max-count="state.quarterGraphData.maxFaultCountItem"
                :min-count="state.quarterGraphData.minFaultCountItem"
                :max-mom="state.quarterGraphData.maxMomRatioItem"
                :min-mom="state.quarterGraphData.minMomRatioItem"
                :max-yoy="state.quarterGraphData.maxYoyBasisItem"
                :min-yoy="state.quarterGraphData.minYoyBasisItem"
              />
            </div>
          </div>

          <empty v-if="!state.data.agentTrend?.agentCountByQuarterList?.length" />
        </div>
      </div>

      <!------------------------------------------ 分布 ------------------------------------------------------->

      <div class="flex-column bg-white pd10 right-box height-all">
        <div class="bold mgb20">代理客户分布</div>

        <div class="flex gap10">
          <div class="flex1 bg-gray pd10">
            <div class="mgb20">客户数</div>
            <div>
              <span class="bold">{{ state.data.agentDistribution.customerCount ?? 0 }}</span>
              <span>个</span>
            </div>
          </div>
          <div class="flex1 bg-gray pd10">
            <div class="mgb20">客户平均代理数</div>
            <div>
              <span class="bold">{{ avgAgent }}</span>
              <span>个</span>
            </div>
          </div>
        </div>

        <!------------------------------------------ 分布item ------------------------------------------------------->

        <div v-if="state.data.agentDistribution?.agentDistributionList?.length" class="flex1 flex-column" style="overflow: hidden">
          <div class="flex-row-center-between mgt30 mgb10">
            <div class="flex-row-center-between gap20">
              <div class="flex-row-center-between gap10">
                <div style="height: 10px; width: 10px; background: #dbdbdb"></div>
                <span>代理数</span>
              </div>
              <div class="flex-row-center-between gap10">
                <div style="height: 10px; width: 10px; background: #1fc16d"></div>
                <span>在线数 </span>
              </div>
            </div>
            <el-link type="primary" @click="toPageListAll">查看全部</el-link>
          </div>

          <div class="flex1" style="overflow: auto">
            <DistibuteItem class="mgb10" v-for="item in state.data.agentDistribution.agentDistributionList?.slice(0, 10)" :data="item" :key="item.customerName" />
          </div>
        </div>

        <empty v-else style="margin: auto" />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { reactive, computed, onMounted, onUnmounted, nextTick } from 'vue'
  import router from '@/router'
  import * as echarts from 'echarts'
  import type { ECharts } from 'echarts'
  import { max, min } from 'xe-utils'
  import request from '@/service'
  import { Ui } from '@/utils'
  import TopOverviewItem from './cpns/top-overview-item.vue'
  import DistibuteItem from './cpns/distribute-item.vue'
  import GraphDesc from './cpns/graph-desc.vue'
  import SelectVue from '@/components/select'
  import type { AgentData, AgentOverview, AgentDistribution, AgentTrend, AgentCountBItem } from './config'
  import { setChartOptions } from './config'
  import empty from '@/components/empty/empty.vue'

  const initData = () => ({
    xAxis: [] as string[],
    seriesFaultCount: [] as number[],
    seriesMomRatio: [] as number[], // 环比
    seriesYoyBasis: [] as number[], // 同比
    maxFaultCountItem: {} as AgentCountBItem,
    minFaultCountItem: {} as AgentCountBItem,
    maxMomRatioItem: {} as AgentCountBItem,
    minMomRatioItem: {} as AgentCountBItem,
    maxYoyBasisItem: {} as AgentCountBItem,
    minYoyBasisItem: {} as AgentCountBItem,
    yAxisRightMax: 100,
    yAxisRightMin: 0
  })

  const state = reactive({
    loading: false,
    data: {
      agentDistribution: {} as AgentDistribution,
      agentOverview: {} as AgentOverview,
      agentTrend: {} as AgentTrend
    },
    monthGraphData: initData(),
    quarterGraphData: initData(),

    quarterQuery: {
      startTime: '',
      endTime: ''
    },
    monthQuery: {
      startTime: '',
      endTime: ''
    }
  })

  let monthRange: string[] = []
  let quarterRange: string[] = []

  let monthChart: ECharts
  let quarterChart: ECharts

  const avgAgent = computed(() => {
    if (!state.data.agentDistribution.customerCount) return 0
    return Math.round(Number(state.data.agentOverview.sumCount) / Number(state.data.agentDistribution.customerCount))
  })

  /**----------------------------methods----------------------------------------------------------------------- */

  const yoyTopObj = computed(() => {
    if (state.data.agentOverview.sequentialGrowth?.startsWith('-')) {
      return {
        text: '环比下降',
        value: state.data.agentOverview.sequentialGrowth?.replace('-', '')
      }
    }

    return {
      text: '环比增长',
      value: state.data.agentOverview.sequentialGrowth
    }
  })

  const toPageListAll = () => {
    router.push({
      path: '/agent/statistic/cpns/view-list-all'
    })
  }

  const resize = () => {
    monthChart.resize()
    quarterChart.resize()
  }

  const initGraph = () => {
    monthChart = echarts.init(document.getElementById('graph-month'))
    quarterChart = echarts.init(document.getElementById('graph-quarter'))

    window.addEventListener('resize', resize)
  }

  const onMonthChange = () => {
    const r = (str: string) => str.replace('.', '')
    const { startTime, endTime } = state.monthQuery
    const { agentCountByMonthList } = state.data.agentTrend
    const list = agentCountByMonthList.filter(item => r(item.cycle) >= r(startTime) && r(item.cycle) <= r(endTime))
    if (!list.length) return Ui.useMessage('warning', '月份间隔无效，请重新选择')
    mapGraphData(monthChart, list, 'monthGraphData')
  }

  const onQuarterChange = () => {
    const r = (str: string) => str.replace('.S', '')

    const { startTime, endTime } = state.quarterQuery
    const { agentCountByQuarterList } = state.data.agentTrend
    const list = agentCountByQuarterList.filter(item => {
      return r(item.cycle) >= r(startTime) && r(item.cycle) <= r(endTime)
    })
    if (!list.length) return Ui.useMessage('warning', '季度间隔无效，请重新选择')
    mapGraphData(quarterChart, list, 'quarterGraphData')
  }

  const setOptions = (echart: ECharts, key: 'monthGraphData' | 'quarterGraphData') => {
    const { xAxis, maxFaultCountItem, yAxisRightMax, yAxisRightMin, seriesFaultCount, seriesYoyBasis, seriesMomRatio } = state[key]

    setChartOptions(echart, xAxis, Number(maxFaultCountItem.count), yAxisRightMax, yAxisRightMin, seriesFaultCount, seriesYoyBasis, seriesMomRatio)
  }

  const mapGraphData = (echart: ECharts, list: AgentCountBItem[], key: 'monthGraphData' | 'quarterGraphData') => {
    state[key].xAxis = list.map(item => item.cycle)
    state[key].seriesFaultCount = list.map(item => Number(item.count))
    state[key].seriesMomRatio = list.map(item => parseFloat(item.sequentialGrowth.replace('%', '')))
    state[key].seriesYoyBasis = list.map(item => parseFloat(item.yearOnYearGrowth.replace('%', '')))

    state[key].maxFaultCountItem = max(list, item => Number(item.count)) as AgentCountBItem
    state[key].minFaultCountItem = min(list, item => Number(item.count)) as AgentCountBItem

    state[key].maxMomRatioItem = max(list, item => parseFloat(item.sequentialGrowth.replace('%', ''))) as AgentCountBItem
    state[key].minMomRatioItem = min(list, item => parseFloat(item.sequentialGrowth.replace('%', ''))) as AgentCountBItem

    state[key].maxYoyBasisItem = max(list, item => parseFloat(item.yearOnYearGrowth.replace('%', ''))) as AgentCountBItem
    state[key].minYoyBasisItem = min(list, item => parseFloat(item.yearOnYearGrowth.replace('%', ''))) as AgentCountBItem

    const minMomRatio = parseFloat(state[key].minMomRatioItem.sequentialGrowth.replace('%', ''))
    const minYoyBasis = parseFloat(state[key].minYoyBasisItem.yearOnYearGrowth.replace('%', ''))

    const maxMomRatio = parseFloat(state[key].maxMomRatioItem.sequentialGrowth.replace('%', ''))
    const maxYoyBasis = parseFloat(state[key].maxYoyBasisItem.yearOnYearGrowth.replace('%', ''))

    state[key].yAxisRightMin = min([minMomRatio, minYoyBasis])
    //@ts-ignore
    state[key].yAxisRightMax = max([maxMomRatio, maxYoyBasis])

    setOptions(echart, key)
  }

  const getGraphData = () => {
    state.loading = true
    request
      .get<AgentData>('/agent/statistics')
      .then(res => {
        if (res.code !== 0) return Ui.useMessage('error', res.msg)
        state.data = res.data
        const { agentCountByMonthList, agentCountByQuarterList } = res.data.agentTrend

        if (!agentCountByMonthList.length && !agentCountByQuarterList.length) return

        monthRange = agentCountByMonthList.map(item => item.cycle)
        quarterRange = agentCountByQuarterList.map(item => item.cycle)

        state.monthQuery.startTime = monthRange[0]
        state.monthQuery.endTime = monthRange.at(-1) as string

        state.quarterQuery.startTime = quarterRange[0]
        state.quarterQuery.endTime = quarterRange.at(-1) as string

        nextTick(() => {
          initGraph()

          // 月度
          mapGraphData(monthChart, agentCountByMonthList, 'monthGraphData')

          // 季度
          mapGraphData(quarterChart, agentCountByQuarterList, 'quarterGraphData')
        })
      })
      .finally(() => (state.loading = false))
  }

  /**----------------------------lifecycle----------------------------------------------------------------------- */

  onMounted(() => {
    getGraphData()
  })

  onUnmounted(() => {
    monthChart.dispose()
    quarterChart.dispose()
    window.removeEventListener('resize', resize)
  })
</script>

<style scoped lang="less">
  // .top {
  //   height: 150px;
  //   flex-shrink: 0;
  // }
  .right-box {
    width: 400px;
  }
</style>
